import React, { Component } from 'react';
import { Select } from 'antd';
import { connect } from 'dva';
import { abortFetch, newAbortCtrl } from '@/helpers/request';
import isFunction from 'lodash/isFunction';
import map from 'lodash/map';

const { Option } = Select;

@connect(({ global }) => ({
  global,
}))
class ComboBox extends Component {
  // 返回一个对象来更新 state
  static getDerivedStateFromProps(nextProps) {
    // Should be a controlled component.
    if ('value' in nextProps) {
      return {
        value: nextProps.value,
      };
    }
    return null;
  }

  constructor(props) {
    super(props);
    this.state = {
      value: props.value || '',
      loading: false,
    };
  }

  componentDidMount() {
    const { dispatch, comboType, onDataLoad } = this.props;
    const $this = this;
    this.setState({ loading: true }, () => {
      $this.abortCtrl = newAbortCtrl();
      dispatch({
        type: 'global/findByCode',
        payload: {
          code: comboType,
          signal: $this.abortCtrl.signal,
        },
      }).then((rsp) => {
        if (isFunction(onDataLoad)) {
          onDataLoad(rsp);
        }
        $this.setState({ loading: false });
      });
    });
  }

  componentWillUnmount() {
    abortFetch(this.abortCtrl);
  }

  handleChange(value) {

    if (!('value' in this.props)) {
      this.setState({ value });
    }
    this.triggerChange(value);
  }

  triggerChange = (changedValue) => {
    // Should provide an event to pass value to Form.
    const onChange = this.props.onChange;
    if (onChange) {
      onChange(changedValue);
    }
  };

  render() {
    if (!this.props.visible) return null;
    return this.renderSel();
  }

  renderSel() {
    const { style, primaryKey, nameKey, nativeProps = {}, global, compData, comboType } = this.props;

    let optData = [];
    if (compData) {
      optData = compData;
    } else if (global && comboType) {
      optData = global[comboType];
    }
    const styleO = style || nativeProps.style || {};
    return (
      <Select value={this.state.value}
              onChange={this.handleChange.bind(this)}
              loading={this.state.loading}
              {...nativeProps}
              style={{ minWidth: '100px', ...styleO }}
      >
        <Option value="">请选择</Option>
        {map(optData, (opt, oK) => (
          <Option key={oK} value={opt[primaryKey]}>
            {opt[nameKey]}
          </Option>
        ))}
      </Select>
    );
  }
}

ComboBox.defaultProps = {
  primaryKey: 'code',
  nameKey: 'name',
  comboType: '', // 枚举类型
  nativeProps: {}, // Select 组件的属性
  visible: true,
  onDataLoad: null, // 数据加载之后的回调
};

export default ComboBox;
